package org.thewares.collection.test;
//import org.thewares.collection.Deque;
import Timer.time;
//import TestDeck.TitledDeque;

abstract class TimeMany(title:String){
      val lst=List((1 to 999 toList,    0),
		   (1 to 10 toList, 1000000),
		   (1 to 100 toList, 100000),
		   (1 to 10000 toList, 1000),
		   (1 to 1000000 toList, 10),
		   (1 to 10000000 toList, 1)
	     ).map(t=> (t._1.reverse,t._2));
      val nil:List[Int]=Nil;

			      
      def execute()={
	    println("=-=-=-="+title)
	    var badness=0d;
	    for ((list,weight) <- lst){
		  val count=if (weight<100) 2 else if (weight < 10001) 20 else 100;
		  val ret=time(count,{
			runOne(list);
		  }); //end time
		  if (list.head != 999){
			val deltaBad= (weight.toDouble * ret.timing.millis +.5).toInt / 1000d;
			println("start="+list.head+", "+ret.timing+", "+deltaBad);
			badness += deltaBad;
	//		println("badness: "+badness+" = ("+ret.timing.millis +"*" + mw +") + "+ob);
		  }
	    }
	    println("badness="+(badness).toInt);
      }
      def runOne(list:List[Int]):List[Int];
}


class TimeDeque(td:Titled[Deque[Int]]) extends TimeMany(td.title){
      val empty=td.empty;
      def runOne(list:List[Int])={
	    var queue=(empty /: list) {case (q:Deque[Int],element:Int) => element::q};
	    var popped=nil;
	    for (i <- 1 to list.length){
		  popped = queue.head :: popped;
		  queue= queue.tail;
	    }
	    popped
      }
}

class TimeList extends TimeMany("List"){
      val empty:List[Int]=Nil;
      def runOne(list:List[Int])={
	    var queue=(empty /: list) {case (q:List[Int],element:Int) => element::q};
	    var popped=nil;
	    for (i <- 1 to list.length){
		  popped = queue.head :: popped;
		  queue= queue.tail;
	    }
	    popped
      }
}
class TimeBitVector extends TimeMany("BitVector"){
      import com.codecommit.collection.BitVector._;
      import com.codecommit.collection.BitVector;
      val empty:BitVector[Int]=new BitVector;
      def runOne(list:List[Int])={
	    var queue=(empty /: list) {case (q:BitVector[Int],element:Int) => q+element};
	    var popped=nil;
	    for (i <- 1 to list.length){
		  popped = queue(queue.length-1) :: popped;
		  queue= queue.pop;
	    }
	    popped
      }
}

class TimeArrayBuffer extends TimeMany("ArrayBuffer"){
      import scala.collection.mutable.ArrayBuffer;
      val empty:ArrayBuffer[Int]=new ArrayBuffer;
      def runOne(list:List[Int])={
	    var queue=(empty /: list) {case (q:ArrayBuffer[Int],element:Int) => q += element; q}.elements;
	    var popped=nil;
	    for (i <- 1 to list.length){
		  popped = queue.next :: popped;
	    }
	    popped
      }
}


class TimeQueue extends TimeMany("Queue"){
      import scala.collection.immutable.Queue._;
      import scala.collection.immutable.Queue;

      val empty:Queue[Int]=Queue.Empty;
      def runOne(list:List[Int])={
	    var queue=(empty /: list) {case (q:Queue[Int],element:Int) => q.enqueue(element)};
	    var popped=nil;
	    
	    for (i <- 1 to list.length){
		  val (head,tail)=queue.dequeue;
		  popped = head :: popped;
		  queue= tail;
	    }
	    popped
      }
}

